package com.nononsenseapps.feeder.net.obs

import com.gitee.wsl.jvm.net.server.HttpCallHandlerFactory
import com.gitee.wsl.jvm.net.server.HttpUriRooterManager.Companion.getPathArray
import com.gitee.wsl.jvm.net.server.IHTTPSession
import com.gitee.wsl.prop.Prop
import com.gitee.wsl.prop.StringProp.Companion.of
import com.nononsenseapps.feeder.db.entity.FeedItem
import com.nononsenseapps.feeder.db.room.MEMO_FEED_ID
import timber.log.Timber
import java.util.Arrays

object VaultHandler {
    const val PATH = "/vault/"
    const val PATH_FILENAME = "$PATH:filename"
    const val PATH_TO_DIRECTORY = "$PATH:pathToDirectory"
    val pathFileName: Prop<String> = of("filename")
    const val NOTE_JSON_MINE_TYPE = "application/vnd.olrapi.note+json"

    class Index : ObsDefaultHandler() {
        override fun getText(session: IHTTPSession): String {
            return """files:
                - "mydocument.md"
                - "somedirectory/""""
        }

        override val bodyMineType: String
            get() = "application/json"

        companion object{
            val Factory = HttpCallHandlerFactory{ Index() }
        }
    }

    class Get : ObsDefaultHandler() {
        var isNoteJson = false
        override fun initProps(session: IHTTPSession, urlParams: Map<String, String>) {
            super.initProps(session, urlParams)
            initPropValue(urlParams, pathFileName)
            val acceptType = session.headers["Accept"]
            if (acceptType != null && NOTE_JSON_MINE_TYPE == acceptType) isNoteJson = true
        }

        override val bodyMineType: String
            get() = if (isNoteJson) NOTE_JSON_MINE_TYPE else "text/markdown"

        override fun getText(session: IHTTPSession): String {
            var fileName: String? = null
            val paths = getPathArray(pathFileName[props]!!)
            if (paths.isNotEmpty()) fileName = paths[paths.size - 1]
            Timber.d(
                "init prop filename:" + pathFileName[props] + "\taccept json:" + isNoteJson + "\t paths:" + Arrays.toString(
                    paths
                )
            )
            return """
                # This is my document
                
                something else here
                """.trimIndent()
        }

        companion object{
            val Factory = HttpCallHandlerFactory{ Get() }
        }
    }

    class Put : ObsDefaultOperateHandler() {
        override fun initProps(session: IHTTPSession, urlParams: Map<String, String>) {
            super.initProps(session, urlParams)
            initPropValue(urlParams, pathFileName)
        }

        override fun getText(session: IHTTPSession): String {
            var fileName: String? = null
            val paths = getPathArray(pathFileName[props]!!)
            if (paths.isNotEmpty()) fileName = paths[paths.size - 1]
            Timber.d(
                "init prop filename:" + pathFileName[props] + "\t paths:" + Arrays.toString(
                    paths
                )
            )
            val bodyText = session.requestBody
            val itemId = feedItemDao!!.isExistWithTitle(fileName!!)
            if (itemId != null) {
                feedItemDao!!.updateFeedItemBody(itemId, bodyText)
            } else {
                val feedItem = FeedItem()
                feedItem.feedId = MEMO_FEED_ID
                feedItem.title = fileName
                feedItem.description = bodyText
                feedItemDao!!.insertFeedItem(feedItem)
            }
            return ""
        }

        companion object{
            val Factory = HttpCallHandlerFactory{ Put() }
        }
    }

    class Post : ObsDefaultOperateHandler() {
        override fun initProps(session: IHTTPSession, urlParams: Map<String, String>) {
            super.initProps(session, urlParams)
            initPropValue(urlParams, pathFileName)
        }

        override fun getText(session: IHTTPSession): String {
            val textStr = session.requestBody
            return ""
        }

        companion object{
            val Factory = HttpCallHandlerFactory{ Post() }
        }
    }

    class Patch : ObsDefaultOperateHandler() {
        override fun initProps(session: IHTTPSession, urlParams: Map<String, String>) {
            super.initProps(session, urlParams)
            initPropValue(urlParams, pathFileName)
            initPropValue(session.headers, HEADING, Content_Insertion_Position, Heading_Boundary)
        }

        override fun getText(session: IHTTPSession): String {
            val textStr = session.requestBody
            return ""
        }

        companion object {
            val HEADING: Prop<String> = of("Heading")
            val Content_Insertion_Position: Prop<String> = of("Content-Insertion-Position")
            val Heading_Boundary: Prop<String> = of("Heading-Boundary", "::")

            val Factory = HttpCallHandlerFactory{ Patch() }

        }
    }

    class Delete : ObsDefaultOperateHandler() {
        override fun getText(session: IHTTPSession): String {
            TODO("Not yet implemented")
        }

        override fun initProps(session: IHTTPSession, urlParams: Map<String, String>) {
            super.initProps(session, urlParams)
            initPropValue(urlParams, pathFileName)
        }

        companion object{
            val Factory = HttpCallHandlerFactory{ Delete() }
        }

    }

    class PathToDirectory : ObsDefaultOperateHandler() {
        override fun initProps(session: IHTTPSession, urlParams: Map<String, String>) {
            super.initProps(session, urlParams)
            initPropValue(urlParams, pathToDirectory)
        }

        override val bodyMineType: String
            get() = "application/json"

        override fun getText(session: IHTTPSession): String {
            return """files:
                - "mydocument.md"
                - "somedirectory/""""
        }

        companion object {
            val pathToDirectory: Prop<String> = of("pathToDirectory")

            val Factory = HttpCallHandlerFactory{ PathToDirectory() }

        }
    }
}
